// Test case for the main input package
(function() {
    module('lily.input.core');

    test('Module defs e reqs', function() {
        expect(3);
        ok(lily, 'lily package');
        ok(lily.input.Manager, "lily.input.Manager namespace");
        ok(lily.input.constants, "lily.input.constants namespace");
    });

    var input = lily.input.Manager, c = lily.input.constants;

    test('install', function() {
        expect(6);

        // get the test case's very own event registering (on top of
        // Prototype's)
        var _observe = Event.observe, cache = {};
        document.observe = function() {
            cache[arguments[1]] = arguments[2];
            _observe.apply(document, arguments);
        }.methodize();

        input.install(input.window);

        document.observe = _observe;

        ok(Object.isFunction(cache['keydown']),'keydown event installed');
        ok(Object.isFunction(cache['keyup']), 'keyup event installed');
        ok(Object.isFunction(cache['mousemove']),
            'mosemove event installed');
        ok(Object.isFunction(cache['mousedown']),
            'mousedown event installed');
        ok(Object.isFunction(cache['mouseup']),
            'mouseup event installed');
        ok(Object.isFunction(cache['mousewheel'])
           || Object.isFunction(cache['DOMMouseScroll']),
           'mousewheel event installed');

        // stop observing stuff
        var events = ['keydown','keyup','mousemove','mousedown','mouseup',
                      'mousewheel', 'DOMMouseScroll'];
        for (var i = events.length; i--; ) {
            document.stopObserving(events[i]);
        }
    });

    test('add_event', function() {
        expect(4);

        input.add_event({type: 'quit'});
        ok(input.isSet('quit'), 'quit event should be set');
         
        input.add_event({type: 'active', active: false});
        ok(input.isSet('active'), 'active event should be set');
        strictEqual(input.state['active'].event.active, false,
            'active event should be false');

        input.add_event({type: 'active', active: true});
        strictEqual(input.state['active'].event.active, true,
            'active event should be true');

    });

    test('keyboard events', function() {
        expect(6);

        input.add_event({type: 'key_down', key: c.K_RETURN});
        ok(input.isSet(c.K_RETURN), 'return key should be set');
        equal(input.state[c.K_RETURN].event.key, 13, 'return key code is 13');
        ok(input.isDown(c.K_RETURN), 'return key should be pressed');
        input.update();
        // add again to make sure it won't overwrite the held state
        input.add_event({type: 'key_down', key: c.K_RETURN});
        ok(input.isHeld(c.K_RETURN), 'return key should be held');
        input.add_event({type: 'key_up', key:  c.K_RETURN});
        ok(input.isUp(c.K_RETURN), 'return should be being released');
        input.update();
        ok(!input.isSet(c.K_RETURN), 'return should not be set anymore');
    });

    test('mouse events', function() {
        expect(16);

        input.add_event({type: 'mouse_button_down', button: c.MB_LEFT});
        ok(input.isSet('MB_' + c.MB_LEFT), 'mouse 1 set');
        ok(input.isDown('MB_' + c.MB_LEFT), 'mouse 1 down');
        input.update();
        ok(input.isHeld('MB_' + c.MB_LEFT), 'mouse 1 held');
        input.add_event({type: 'mouse_button_down', button: c.MB_RIGHT});
        ok(input.isDown('MB_' + c.MB_RIGHT), 'mouse 3 down');
        ok(input.isHeld('MB_' + c.MB_LEFT), 'mouse 1 still held');

        input.add_event({type: 'mouse_button_up', button: c.MB_LEFT});
        ok(input.isUp('MB_' + c.MB_LEFT), 'mouse 1 up');
        input.update();
        ok(!input.isSet('MB_' + c.MB_LEFT), 'mouse 1 not set anymore');

        equal(input.wheel_delta, 0, 'wheel delta not changed');
        input.add_event({type: 'mouse_wheel', delta: 100});
        equal(input.wheel_delta, 100, 'wheel delta should be 100');
        
        input.mouse_x = 0; input.mouse_y = 0;
        input.mouse_delta = [0, 0];
        input.add_event({type: 'mouse_motion', ev: {pointer: [10, 100]}});
        equal(input.mouse_x, 10, 'mouse x should be 10');
        equal(input.mouse_y, 100, 'mouse y should be 100');
        deepEqual(input.mouse_delta, [0, 0], 'mouse motion not captured yet');

        input.update();
        deepEqual(input.mouse_delta, [10, 100], 'mouse delta');

        input.add_event({type: 'mouse_motion', ev: {pointer: [30, 50]}});
        equal(input.mouse_x, 30, 'mouse x should be 30');
        equal(input.mouse_y, 50, 'mouse y should be 50');
        input.update();
        deepEqual(input.mouse_delta, [20, -50], 'mouse delta');
    });    
}());